
  var util = require ('util');
  var common = require ('./common');

  var Treexy = module.exports = function () {
    this._initTreexy.apply (this, arguments);
  }
  
  Treexy.TreexyNode = require ('./treexy-node');
  
  Treexy.SPACES = 2;
  Treexy.MIXIN_PREFIX = '@mixin ';

  Treexy._abbreviations = {
    '!!!'           : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
    '!!! Strict'    : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
    '!!! Frameset'  : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
    '!!! 5'         : '<!DOCTYPE html>',
    '!!! 1.1'       : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
    '!!! Basic'     : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
    '!!! Mobile'    : '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">',
    '!!! RDFa'      : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">'
  }

  Treexy.prototype._initTreexy = function () {
    // ...
  }
  
  Treexy.prototype.compile = function (data) {
    try {
      var rootElement = new Treexy.TreexyNode ();
      var primaryTree = this._buildPrimaryTree (data);
      var recursiveCreateNodes = function (primaryTreeNode, treexyNode) {
        for (var i in primaryTreeNode) {
          var newTreeNode = new Treexy.TreexyNode (treexyNode, primaryTreeNode[i]['string']);
          recursiveCreateNodes (primaryTreeNode[i]['content'], newTreeNode);
        }
      }
      recursiveCreateNodes (primaryTree.contents, rootElement);
      //console.log (primaryTree.mixins);
      return rootElement.toHtml ();
    } catch (e) {
      console.log (e.message);
      throw (e);
    }
  }
  
  Treexy.prototype._buildPrimaryTree = function (data) {
    var rxFirstNonSpace = /[^\ ]/
    var lines = data.split ('\n');
    var root = {
      string: '',
      content: []
    };
    var mixins = '';
    var currentLevel = 0;
    var levelStack = [root];
    for (var i in lines) {
      var line = lines[i];
      var rxres = rxFirstNonSpace.exec (line);
      if (rxres === null)
        continue;
      var newLevel = rxres['index'] / Treexy.SPACES + 1;
      
      if (line.indexOf (Treexy.MIXIN_PREFIX) == 0 && newLevel == 1) {
        mixinStarted = true;
      } else if (newLevel == 1) {
        mixinStarted = false;
      }
      
      if (mixinStarted) {
        mixins += line + '\n';
      } else {
        if (newLevel - currentLevel > 1)
          throw new Error ('Error at line ' + (i * 1 + 1) + ': Bad level');
        line = line.substr (rxres['index']);
        for (var i in Treexy._abbreviations)
          if (line == i)
            line = Treexy._abbreviations[i];
        if (currentLevel >= newLevel) {
          for (var j = 0, times = currentLevel - newLevel + 1; j < times; j++)
            levelStack.pop ();
        }
        currentLevel = newLevel;
        var newTreeNode = {
          string: line,
          content: []
        }
        levelStack[currentLevel - 1].content.push (newTreeNode);
        levelStack.push (newTreeNode);
      }
    }
    return {
      contents: root.content,
      mixins: mixins
    };
  }

